// 执行命令  ts-node Interfaces.ts
// 接口与类型别名的区别
// Objects / Functions
// TypeScript 的核心原则之一是对值所具有的结构进行类型检查。 而接口的作用就是为这些类型命名和为你的代码或第三方代码定义数据模型。
// type(类型别名)会给一个类型起个新名字。 type 有时和 interface 很像，但是可以作用于原始值（基本类型），联合类型，元组以及其它任何你需要手写的类型。起别名不会新建一个类型 - 它创建了一个新 名字来引用那个类型。给基本类型起别名通常没什么用，尽管可以做为文档的一种形式使用。
// Interface
interface Point {
  x: number,
  y: number
}
interface SetPoint {
  (x: number, y: number): void;
}

// Type alias
type Point1 = {
  x: number;
  y: number;
};
type SetPoint1 = (x: number, y: number) => void;


// Other Types
// primitive
type Name = string;
// object
type PartialPointX = { x: number };
type PartialPointY = { y: number };
// union
type PartialPoint = PartialPointX | PartialPointY
// tuple
type Data = [number, string]
// dom
let div = document.createElement('div')
type B = typeof div


// 接口可以定义多次,类型别名不可以    与类型别名不同，接口可以定义多次，会被自动合并为单个接口
interface Point { x: number; }
interface Point { y: number; }
const point12: Point = { x: 1, y: 2 };


// 扩展    两者的扩展方式不同，但并不互斥。接口可以扩展类型别名，同理，类型别名也可以扩展接口。 接口的扩展就是继承，通过 extends 来实现。类型别名的扩展就是交叉类型，通过 & 来实现。
// 接口扩展接口
interface PointX {
  x: number
}
interface PointY extends PointX {
  y: number
}
const pointYY: PointY = {
  x: 1,
  y: 1
}
// 类型别名扩展类型别名
type PointIX = {
  x: number
}
type PointIY = PointX & {
  y: number
}
// 接口扩展类型别名
interface PointIY1 extends PointIX {
  y: number
}
// 类型别名扩展接口
type PointY1 = PointX & { y: number }


console.log('Interfaces: ', tomInter2)